home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 15 / BBS in a box XV-1.iso / Files / Util / N-O / OneSpaceInit.sit / OneSpace INIT Documentation / card_4791.txt < prev    next >
Encoding:
Text File  |  1989-11-22  |  9.4 KB  |  269 lines

  1. -- card: 4791 from stack: in
  2. -- bmap block id: 5107
  3. -- flags: 4000
  4. -- background id: 2707
  5. -- name: 
  6.  
  7.  
  8. -- part 1 (field)
  9. -- low flags: 01
  10. -- high flags: 2007
  11. -- rect: left=43 top=182 right=285 bottom=463
  12. -- title width / last selected line: 0
  13. -- icon id / first selected line: 0 / 0
  14. -- text alignment: 0
  15. -- font id: 3
  16. -- text size: 9
  17. -- style flags: 0
  18. -- line height: 12
  19. -- part name: code
  20.  
  21.  
  22. -- part 2 (button)
  23. -- low flags: 00
  24. -- high flags: A002
  25. -- rect: left=205 top=286 right=308 bottom=305
  26. -- title width / last selected line: 0
  27. -- icon id / first selected line: 0 / 0
  28. -- text alignment: 1
  29. -- font id: 3
  30. -- text size: 9
  31. -- style flags: 0
  32. -- line height: 12
  33. -- part name: Copy Source Code
  34. ----- HyperTalk script -----
  35. on mouseUp
  36.   select text of cd fld "code"
  37.   doMenu "Copy Text"
  38.   select empty
  39. end mouseUp
  40.  
  41.  
  42.  
  43. -- part contents for background part 1
  44. ----- text -----
  45. This init comes from Maurice Volaski, 29 Callodine Ave. Amherst, NY 14226-3125, 716-838-6663. Internet: volaski@contra.med.buffalo.edu. 
  46. Below is the source code listing for the OneSpace init written in THINK C. 
  47.  
  48.  
  49. -- part contents for card part 1
  50. ----- text -----
  51. Special thanks to Ken McLeod for answering questions regarding this code. Thanks also to Mark Pierce for doing such wonderful startup icons.
  52.  
  53. /*=================================================================
  54. The following is the source code for the OneSpace INIT by
  55. Maurice Volaski (volaski@contra.med.buffalo.edu)
  56. prepared in THINK C.
  57.  
  58. In typesetting it is a general rule to use one space character at a time.
  59. Thus, as a typesetting tool, the Macintosh differs from its earlier 
  60. predecessors, especially the typewriter, where it is, for example, a 
  61. general rule to type two spaces at the end of a sentence. 
  62. The init‚Äôs purpose is to prevent users from typing more than one space in 
  63. a row, especially by accident, thus preserving the standards of 
  64. typesetting as well as the integrity of the Macintosh as a typesetting 
  65. tool. 
  66.  
  67. To adhere to the user interface guidelines, the init can be switched
  68. on or off upon command. To toggle the init‚Äôs on/off setting use
  69. command-shift-spacebar.
  70.  
  71. Complete conerning using this init are discussed in the user‚Äôs 
  72. documentation.
  73.  
  74. The following commented material concerning inits in general
  75. as well this one is from Ken McLeod:
  76.  
  77.  
  78.   IMPORTANT: You should never write a patch which is a ‚Äútail‚Äù
  79.   patch, since various system routines check the return address
  80.   on the stack to see who called them (see technote #212). A
  81.   ‚Äútail‚Äù patch is one which calls the original routine as a
  82.   subroutine call, after which control returns to the patch code.
  83.   A correctly-written patch jumps directly to the original routine
  84.   after doing whatever it does; control doesn‚Äôt return to the patch
  85.   code until the next time that trap is called.
  86.   
  87.   GetNextEvent is a special case, since a patch to GNE will
  88.   usually need to alter the EventRecord AFTER it has been filled
  89.   in by GNE, but before it gets back to the original caller.
  90.   Apple has provided a documented method for doing this WITHOUT
  91.   having to use a tail patch. The following is excerpted from
  92.   technote #85:
  93.  
  94. > You must call GetNextEvent periodically. GetNextEvent uses a
  95. > filter (GNE filter) which allows for a routine to be installed
  96. > which overrides (or augments) the behavior of the system. The
  97. > GNE filter is installed by pointing the low-memory global jGNEFilter
  98. > (a long word at $29A) to the routine. After all other GNE processing
  99. > is complete, the routine will be called with A1 pointing to the
  100. > event record and D0 containing the boolean result. The filter may
  101. > then modify the event record or change the function result by
  102. > altering the word on the stack at 4(A7). This word will match D0
  103. > initially, of course.
  104.  
  105.   At startup, our INIT simply installs a pointer to our ModifyEvent()
  106.   function in the jGNEFilter low-memory global, saving the pointer
  107.   it currently contains. When ModifyEvent() gets control, it alters
  108.   the event record, then jumps to the saved jGNEFilter function, or
  109.   returns if the saved pointer was nil.
  110.   
  111.   Note that patching GetNextEvent has no effect on desk accessories,
  112.   since DA‚Äôs are drivers, and get their event records handed to them
  113.   via the csParam field of a parameter block (in other words, they
  114.   don‚Äôt call GetNextEvent.)  Modification of events for drivers is
  115.   somewhat more complex, and ‚Äúoutside the scope of this example.‚Äù
  116.  
  117.   Remember to set the ‚ÄúSystem Heap‚Äù and ‚ÄúLocked‚Äù bits for the
  118.   INIT resource in the ‚ÄúSet Project Type...‚Äù dialog! Remember to
  119.   check the <MacHeaders> option on in the Options dialog. Also, don‚Äôt
  120.   forget to include MacTraps in your project!
  121.  
  122.   =================================================================*/
  123.  
  124.  
  125.  
  126. #include <SetUpA4.h>/*SetUpA4.h generates inline code here, as well as 4 bytes of
  127.    storage for A4 (storage for globals is at end of our code) */
  128.  
  129. #define NIL 0L
  130. #define procID 0
  131. #define GetNextEventTrap 0xA970
  132.  
  133. extern long jGNEFilter : 0x29A;/*low-memory global (Ptr) */
  134. long savedjGNEFilter;/*storage for old jGNEFilter ptr */
  135. EventRecord *theEvent;/*storage for ptr to EventRecord */
  136. short isValidEvent;/*storage for boolean result */
  137. int spaceCounter;/*storage for counting # of spaces typed */
  138. Boolean trapSpace;/*storage for turning INIT on or off */
  139.  
  140. /*the following function will be called by GetNextEvent, 
  141. so it must be declared as a pascal function, like just 
  142. about everything else which can be called by the system! */
  143.    
  144. pascal void ModifyEvent()
  145. {/* as per technote #85, A1 contains the EventRecord 
  146. pointer and D0 contains the result GNE will return. 
  147. We‚Äôll have to save them before calling SetUpA4(), since 
  148. that routine changes register A1, and we'll also need 
  149. to restore them before leaving! */
  150.   asm {
  151.     move.l  A1,-(sp);push event ptr from A1 onto stack
  152.     move.w  D0,-(sp);push event validity word from D0
  153.   }
  154.   
  155.   /* now it‚Äôs safe to get our globals! */
  156.  
  157.   SetUpA4();
  158. /*get the values we saved. At this point, A4 (4 bytes) has 
  159. been pushed on top of them by SetUpA4(), so we can‚Äôt just 
  160. pop them off the stack here; however, we know their offsets 
  161. from the current stack pointer (which has just been moved up 
  162. by 4). */
  163.   asm {
  164.     move.w  4(sp),isValidEvent;get saved value from stack
  165.     move.l  6(sp),theEvent;get saved pointer from stack
  166.   }
  167.   if (isValidEvent)
  168.   /*This is where the init does its job. If the event is keydown or 
  169.   autokey and the character is a space, it increments the space 
  170.   counter by one. If the command and shift keys were held down
  171.   with the space character, the init sets its on/off setting
  172.   to the opposite of its current state and decrements the 
  173.   spaceCounter to 0. If the init is set on, it proceeds to check
  174.   how many spaces have been typed. If one space has been typed, it
  175.   decrements the space counter by one and alters the EventRecord
  176.   to record a null event and alerts the user that more than
  177.   one space is not allowed. Otherwise, if the character is not a 
  178.   space it sets the space counter to 0. */
  179.   
  180.      if ((theEvent->what == keyDown) ||(theEvent->what == autoKey)) {
  181. if ((theEvent->message & 0xFF) == ' ') {
  182.       spaceCounter+=1;
  183.       if ((theEvent->modifiers & shiftKey) !=0 && (theEvent->modifiers & cmdKey)) {
  184.        trapSpace=!trapSpace;
  185. spaceCounter=0;
  186. }
  187.       if (trapSpace) {
  188.       if (spaceCounter==2) {
  189.      theEvent->what=NIL;
  190.      isValidEvent=false;
  191.      spaceCounter=1;
  192.      SysBeep(1);
  193.      }
  194.      }
  195.      }
  196.      else 
  197.       spaceCounter=0;
  198.     }
  199. /*now decide how to return. If our saved jGNEFilter isn‚Äôt NIL, we
  200.  need to jump to someone else‚Äôs jGNEFilter routine (unless, for
  201.  some unforeseen reason, the saved routine is ModifyEvent, which
  202. would send us on a trip to recursion hell!). Otherwise, we‚Äôll
  203. just return normally. Remember to restore A1 and D0 (we saved
  204. them on the stack...) */
  205.     asm {
  206.       move.l  savedjGNEFilter,A0  ;put saved addr in A0
  207.       move.l  (sp)+,A4             ;RestoreA4 (undoes SetUpA4)
  208.                                 ;(can‚Äôt access globals now...)
  209.       move.w  (sp)+,D0   ;get it off the stack first, put it back in D0
  210.   move.l  (sp)+,A1   ;get saved ER pointer off stack, too
  211.  jmp     (A0)       ;jump to next filter routine
  212.     }
  213. }
  214.  
  215.  
  216. /*main‚Äîonce-only code that saves the pointer to us, sets
  217.   up our static storage, and installs the patch. */
  218.  
  219.  
  220. /*this code calls the compiled CShowINIT */
  221. /*to load the various startup icons */
  222. void showIcon(iconID,move)
  223. int iconID;
  224. int move;
  225. {
  226. Handle procH;
  227.  
  228. if ((procH = GetResource('PROC', procID)) != NIL){
  229. HLock(procH);
  230. CallPascal(iconID, move, *procH);
  231. HUnlock(procH);
  232. }
  233. }
  234.  
  235. void main(){
  236. Handle myHandle;
  237. Ptr myPtr; 
  238. long theTicks;
  239.         
  240. asm {
  241.     move.l A0, myPtr
  242.   }
  243. RememberA0();
  244. SetUpA4();
  245. if (Button()) {
  246.   showIcon(130,-1);/*show the icon to indicate that */
  247.   /*init isn‚Äôt loading */
  248.   }
  249.   else {
  250.   myHandle = RecoverHandle(myPtr); /*get handle to our rsrc */
  251.    DetachResource(myHandle);        /*so it won‚Äôt go away */
  252.    HLock(myHandle);                 /*lock it down! */
  253.     showIcon(128,0);/*show the startup icon */
  254.     Delay(30,&theTicks);/*give a chance to see it */
  255.     showIcon(129,-1);/*do animation icon */
  256.    trapSpace=true;/*turn multiple space trapping on */
  257.     spaceCounter=0;/*initialize the space counter‚Äî */
  258.      /*no spaces have been typed. */
  259.     savedjGNEFilter = jGNEFilter;/*save address of old jGNEFilter routine */
  260.     jGNEFilter = (long) ModifyEvent;/*point jGNEFilter to our ModifyEvent function */
  261.     
  262.   }
  263.   RestoreA4();
  264. }
  265.  
  266.  
  267. -- part contents for background part 4
  268. ----- text -----
  269. 4 of 4